﻿using System;
using System.Collections.Specialized;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using Basmus;
using Basmus.ReadWrite;
using Basmus.Resources;
using Basmus.Values;
using Basmus.Values.Attributive;
using Basmus.Values.Web;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Ninject;

namespace Basmus.Tests.WebLink
{
    [TestClass]
    public class WebLinkServiceTests_SetModel_WithoutLibraryAttributes
    {
        private WebLinkService _service;

        [TestInitialize]
        public void Initialize()
        {
            var kernal = new StandardKernel(new TestNinjectModule());
            _service = kernal.Get<WebLinkService>();
           
           // _service = new WebLinkService(StandartVirtualPathService.Default,
           //                               new StringValuesService(ReadWriteService.Default, new ContextService()), new RouteInfoService(), new ContextService());
        }

        #region Set int property tests

        [TestMethod]
        public void SetModel_Null_SetIntPropertyToDefault()
        {
            //Arrange
            var stubProvider = new Mock<IValuesProvider<string>>();
            stubProvider.Setup(p => p.GetValues("Id")).Returns((IEnumerable<string>)null);
            var model = new TestData.UrlModel();

            //Act
            _service.SetModel(typeof(TestData.UrlModel), model, stubProvider.Object);

            //Assert
            Assert.AreEqual(default(int), model.Id);
        }

        [TestMethod]
        public void SetModel_SingleEmptyString_SetIntPropertyToDefault()
        {
            //Arrange
            var stubProvider = new Mock<IValuesProvider<string>>();
            stubProvider.Setup(p => p.GetValues("Id")).Returns(new[] { "" });
            var model = new TestData.UrlModel();

            //Act
            _service.SetModel(typeof(TestData.UrlModel), model, stubProvider.Object);

            //Assert
            Assert.AreEqual(default(int), model.Id);
        }

        [TestMethod]
        public void SetModel_SingleValidIntegerString_SetIntPropertyToThisValue()
        {
            //Arrange
            var stubProvider = new Mock<IValuesProvider<string>>();
            stubProvider.Setup(p => p.GetValues("Id")).Returns(new[] { "10" });
            var model = new TestData.UrlModel();

            //Act
            _service.SetModel(typeof(TestData.UrlModel), model, stubProvider.Object);

            //Assert
            Assert.AreEqual(10, model.Id);
        }

        [TestMethod]
        public void SetModel_FirstEmptyAndSecondValidIntegerString_SetIntPropertyToSecondValue()
        {
            //Arrange
            var stubProvider = new Mock<IValuesProvider<string>>();
            stubProvider.Setup(p => p.GetValues("Id")).Returns(new[] { "", "9" });
            var model = new TestData.UrlModel();

            //Act
            _service.SetModel(typeof(TestData.UrlModel), model, stubProvider.Object);

            //Assert
            Assert.AreEqual(9, model.Id);
        }

        [TestMethod]
        public void SetModel_FirstValidIntegerString_SetIntPropertyToFirstValue()
        {
            //Arrange
            var stubProvider = new Mock<IValuesProvider<string>>();
            stubProvider.Setup(p => p.GetValues("Id")).Returns(new[] { "67", "", "ggg" });
            var model = new TestData.UrlModel();

            //Act
            _service.SetModel(typeof(TestData.UrlModel), model, stubProvider.Object);

            //Assert
            Assert.AreEqual(67, model.Id);
        }

        #endregion

        [TestMethod]
        public void SetModel_ValidIntegerStrings_SetIntCollectionPropertyToTheseValues()
        {
            //Arrange
            var stubProvider = new Mock<IValuesProvider<string>>();
            stubProvider.Setup(p => p.GetValues("ObjectIds")).Returns(new[] { "10", "20", "0", "22" });
            var model = new TestData.UrlModel();

            //Act
            _service.SetModel(typeof(TestData.UrlModel), model, stubProvider.Object);

            //Assert
            CollectionAssertHelper.AreEqual(new[] { 10, 20, 0, 22 }, model.ObjectIds);
        }
        
        [TestMethod]
        public void SetModel_SingleEmptyString_SetIntCollectionPropertyToEmptyCollection()
        {
            //Arrange
            var stubProvider = new Mock<IValuesProvider<string>>();
            stubProvider.Setup(p => p.GetValues("ObjectIds")).Returns(new[] { "" });
            var model = new TestData.UrlModel();

            //Act
            _service.SetModel(typeof(TestData.UrlModel), model, stubProvider.Object);

            //Assert
            CollectionAssertHelper.AreEqual(Enumerable.Empty<int>(), model.ObjectIds);
        }
        
        [TestMethod]
        public void SetModel_SingleValidIntegerString_SetNullableIntPropertyToThisValue()
        {
            //Arrange
            var stubProvider = new Mock<IValuesProvider<string>>();
            stubProvider.Setup(p => p.GetValues("OptionalObjectId")).Returns(new[] { "13" });
            var model = new TestData.UrlModel();

            //Act
            _service.SetModel(typeof(TestData.UrlModel), model, stubProvider.Object);

            //Assert
            Assert.AreEqual(13, model.OptionalObjectId);
        }
        
        [TestMethod]
        public void SetModel_SingleEmptyString_SetNullableIntPropertyToNull()
        {
            //Arrange
            var stubProvider = new Mock<IValuesProvider<string>>();
            stubProvider.Setup(p => p.GetValues("OptionalObjectId")).Returns(new[] { "" });
            var model = new TestData.UrlModel();

            //Act
            _service.SetModel(typeof(TestData.UrlModel), model, stubProvider.Object);

            //Assert
            Assert.IsFalse(model.OptionalObjectId.HasValue);
        }

        
        [TestMethod]
        public void SetModel_FirstValidIntegerStrings_SetNullableIntPropertyToFirstValue()
        {
            //Arrange
            var stubProvider = new Mock<IValuesProvider<string>>();
            stubProvider.Setup(p => p.GetValues("OptionalObjectId")).Returns(new[] { "146", "5", "", "44" });
            var model = new TestData.UrlModel();

            //Act
            _service.SetModel(typeof(TestData.UrlModel), model, stubProvider.Object);

            //Assert
            Assert.AreEqual(146, model.OptionalObjectId);
        }

        [TestMethod]
        public void SetModel_FirstEmptyString_SetNullableIntPropertyToNull()
        {
            //Arrange
            var stubProvider = new Mock<IValuesProvider<string>>();
            stubProvider.Setup(p => p.GetValues("OptionalObjectId")).Returns(new[] { "", "51", "", "2" });
            var model = new TestData.UrlModel();

            //Act
            _service.SetModel(typeof(TestData.UrlModel), model, stubProvider.Object);

            //Assert
            Assert.IsFalse(model.OptionalObjectId.HasValue);
        }
    }
}
